package com.takanafu.haru.core{
	import com.takanafu.haru.code.CodeBase;
	import com.takanafu.haru.code.CodeObject;
	import com.takanafu.haru.code.CodeSymbol;
	
	import flash.utils.Dictionary;
	
	import mx.collections.ArrayCollection;
	
	public class Frame{
		private var locals:Array = new Array();
		private var object:CodeObject;
		
		public function Frame(o:CodeObject=null){
			this.object = o;
		}
		public function size():int{
			return this.locals.length;
		}
		public function pushLocals(table:Dictionary):void{
			this.locals.push(table);
		}
		public function popLocals():void{
			this.locals.pop();
		}
		public function hasSymbol(sym:CodeSymbol):Boolean{
			if(this.locals.length > 0){
				var table:ArrayCollection = this.locals[0] as ArrayCollection;
				
				if(table.hasOwnProperty(sym) == true){
					return true;
				}
			}
			if(this.object != null){
				return object.hasSymbol(sym);
			}
			return false;
		}
		public function getSymbolValue(sym:CodeSymbol):CodeBase{
			if(this.locals.length > 0){
				var table:ArrayCollection = this.locals[0] as ArrayCollection;
				
				if(table.hasOwnProperty(sym) == true){
					return table[sym];
				}
			}
			if(this.object != null){
				return object.getSymbolValue(sym);
			}
			return null;
		}
		public function setSymbolValue(sym:CodeSymbol,c:CodeBase):void{
			if(this.locals.length > 0){
				var table:ArrayCollection = this.locals[0] as ArrayCollection;
				
				if(table.hasOwnProperty(sym) == true){
					table[sym] = c;
					return;
				}
			}
			if(this.object != null){
				try{
					this.object.setSymbolValue(sym,c);
				}catch(e:Error){
					
				}
			}
		}
		public function def(sym:CodeSymbol,c:CodeBase):void{
			var table:ArrayCollection = this.locals[0] as ArrayCollection;
				
			if(table.hasOwnProperty(sym) == true){
				throw new Error("変数"+sym.toString()+"は定義済みです。");
			}
			table[sym] = c;
		}
	}
}